﻿using System;
using System.Drawing;
using System.IO;
using System.Runtime.InteropServices;
using System.Windows.Media.Imaging;

namespace 窗口背景透明
{
    /// <summary>
    /// 文件图标提取
    /// </summary>
    public class FileIconExtractor
    {
        [DllImport("shell32.dll")]
        private static extern IntPtr SHGetFileInfo(string pszPath, uint dwFileAttributes, ref SHFILEINFO psfi, uint cbFileInfo, uint uFlags);

        private const uint SHGFI_ICON = 0x000000100;
        private const uint SHGFI_LARGEICON = 0x000000000; // 大图标
        private const uint SHGFI_SMALLICON = 0x000000001; // 小图标
        private const uint SHGFI_USEFILEATTRIBUTES = 0x000000010; // 使用文件属性

        [StructLayout(LayoutKind.Sequential)]
        private struct SHFILEINFO
        {
            public IntPtr hIcon;
            public int iIcon;
            public uint dwAttributes;
            [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 260)]
            public string szDisplayName;
            [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 80)]
            public string szTypeName;
        }

        /// <summary>
        /// 根据文件路径提取文件图标
        /// </summary>
        /// <param name="extension"></param>
        /// <param name="largeIcon"></param>
        /// <returns></returns>
        public static BitmapImage GetFileIcon(string extension, bool largeIcon = true)
        {
            try
            {
                if (!extension.StartsWith("."))
                {
                    extension = "." + extension;
                }

                SHFILEINFO shinfo = new SHFILEINFO();
                uint flags = SHGFI_ICON | SHGFI_USEFILEATTRIBUTES;

                if (largeIcon)
                {
                    flags += SHGFI_LARGEICON;
                }
                else
                {
                    flags += SHGFI_SMALLICON;
                }

                SHGetFileInfo(extension, 0x80, ref shinfo, (uint)Marshal.SizeOf(shinfo), flags);

                Icon icon = Icon.FromHandle(shinfo.hIcon);
                using (MemoryStream ms = new MemoryStream())
                {
                    icon.ToBitmap().Save(ms, System.Drawing.Imaging.ImageFormat.Png);
                    ms.Seek(0, SeekOrigin.Begin);

                    BitmapImage bitmapImage = new BitmapImage();
                    bitmapImage.BeginInit();
                    bitmapImage.StreamSource = ms;
                    bitmapImage.CacheOption = BitmapCacheOption.OnLoad;
                    bitmapImage.EndInit();

                    return bitmapImage;
                }

            }
            catch
            {
                // Debug.WriteLine("图标错误！");
                return null;
            }
        }
    }
}
